package com.stary.music.api.source.wangyiyun;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.stary.music.api.vo.MusicInfo;
import com.stary.music.api.vo.PlayListInfo;
import com.stary.music.exception.MyMusicException;
import com.stary.music.util.DateTimeUtils;
import com.stary.music.util.HTTPUtils;
import com.stary.music.util.PropertiesUtils;

/**
 * 网易云音乐API
 * @author stary
 * @date 2018年6月13日 下午2:53:28
 */
public class WangYiYunMusic {

	private static final Logger logger=LoggerFactory.getLogger(WangYiYunMusic.class);
	private static final String PREFIX="wangyiyun.music";	
	private static PropertiesUtils pUtils=null;	


	static {
		pUtils=new PropertiesUtils();
		pUtils.setKeyPrefix(PREFIX);
	}

	/**
	 * 根据关键词搜索歌曲信息 <br>
	 * 关键词：歌曲名、专辑、歌手 
	 * @param searchRequest
	 * @return
	 */
	public List<MusicInfo> searchMusicList(WangYiYunSearchRequest searchRequest){
		if(searchRequest.getS()==null || searchRequest.getS().isEmpty()){
			logger.error("缺少参数或出现不能识别的参数");
			throw new MyMusicException("a parameter is missing or unrecognized");
		}
		List<MusicInfo> list=null;
		StringBuffer buffer=new StringBuffer();
		JSONObject searchRequestJSON=(JSONObject) JSONObject.toJSON(searchRequest);
		for (Entry<?, ?> entry : searchRequestJSON.entrySet()) {
			buffer.append("&" + entry.getKey() + "=" + entry.getValue());
		}
		buffer.replace(0, 1, "");
		logger.debug("搜索歌曲信息入参----->>{}",buffer.toString());
		pUtils.setKey("search");
		try {
			/*
			 * 反反爬机制
			 */ 
			Map<String, String> headerMap=new HashMap<>();
			headerMap.put("Referer", "https://music.163.com/");
			headerMap.put("Accept", "*/*");
			headerMap.put("User-Agent", "Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36");
			String resp=HTTPUtils.sendPost(pUtils.getStringValue(),headerMap, buffer.toString());
			logger.debug("搜索歌曲信息出参----->>{}",resp);
			if(!resp.isEmpty()){
				JSONObject respJSON = JSONObject.parseObject(resp);
				if (respJSON.getInteger("code")== 200) {
					if(respJSON.containsKey("result")){
						String result=respJSON.getString("result");
						JSONObject resultJSON = JSONObject.parseObject(result);
						if (searchRequest.getType()==1 && resultJSON.containsKey("songs")) {
							JSONArray songsArray = resultJSON.getJSONArray("songs");
							list=new ArrayList<MusicInfo>();
							MusicInfo info=null;
							pUtils.setKey("src");
							for (int i = 0; i < songsArray.size(); ++i) {
								String song=songsArray.getString(i);
								JSONObject songJSON = JSONObject.parseObject(song);
								info=new MusicInfo();
								// 歌名
								String name = songJSON.getString("name");
								info.setName(name);						
								// 歌曲ID
								String id = songJSON.getString("id");
								info.setId(id);
								// 歌曲外链
								String src=pUtils.getStringValue().replace("SONG_ID", id != null ? id.toString() : "");
								info.setSrc(src);
								JSONArray artistsArray = songJSON.getJSONArray("artists");
								// 歌手 艺术家
								StringBuffer artist = new StringBuffer();
								for (int j = 0; j < artistsArray.size(); ++j) {
									String artists = artistsArray.getString(j);
									JSONObject artistsJSON = JSONObject.parseObject(artists);
									artist.append(artistsJSON.getString("name"));
									if (j < artistsArray.size() - 1) {
										artist.append("/");
									}
								}
								info.setSinger(artist.toString());
								// 专辑
								String album = songJSON.getString("album");
								JSONObject albumJSON = JSONObject.parseObject(album);
								String albumName=albumJSON.getString("name");
								info.setAlbum(albumName);
								// 封面
								String cover = albumJSON.getString("picUrl");
								info.setCover(cover);
								// 歌词
								if(searchRequest.getShowLrc()!=0){
									// 歌词
									String lyric = getMusicLyric(id);	
									info.setLyric(lyric);
								}
													
								// 集合
								list.add(info);
							}
						}
					}

				}
			}
		} catch (Exception e) {
			logger.error("搜索歌曲信息出现异常",e);
		}

		return list;
	}
	/**
	 * 获取用户歌单信息  如：uid=88573201
	 * @param userPlayListRequest
	 * @return
	 */
	public List<PlayListInfo> getUserPlayList(UserPlayListRequest userPlayListRequest){
		if(userPlayListRequest.getUid()==null || userPlayListRequest.getUid()<1){
			logger.error("缺少参数或出现不能识别的参数");
			throw new MyMusicException("a parameter is missing or unrecognized");
		}
		List<PlayListInfo> list=null;
		StringBuffer buffer=new StringBuffer();
		JSONObject searchRequestJSON=(JSONObject) JSONObject.toJSON(userPlayListRequest);
		for (Entry<?, ?> entry : searchRequestJSON.entrySet()) {
			buffer.append("&" + entry.getKey() + "=" + entry.getValue());
		}
		buffer.replace(0, 1, "");
		logger.debug("用户歌单入参----->>{}",buffer.toString());
		pUtils.setKey("user-playlist");
		try {
			String resp=HTTPUtils.sendGet(pUtils.getStringValue(), buffer.toString());
			logger.debug("用户歌单出参----->>{}",resp);
			if(!resp.isEmpty()){
				JSONObject respJSON = JSONObject.parseObject(resp);
				if (respJSON.getInteger("code")== 200) {
					if(respJSON.containsKey("playlist")){
						JSONArray playlistJSONArray=respJSON.getJSONArray("playlist");
						list=new ArrayList<>();
						PlayListInfo info=null;
						for (int i = 0; i < playlistJSONArray.size(); i++) {							
							String playlist=playlistJSONArray.getString(i);
							JSONObject playlistJSON=JSONObject.parseObject(playlist);
							info=new PlayListInfo();
							// 名称
							String name=playlistJSON.getString("name");
							info.setName(name);
							// ID
							String id=playlistJSON.getString("id");
							info.setId(id);
							// 封面
							String cover=playlistJSON.getString("coverImgUrl");
							info.setCover(cover);
							// 创建人信息
							String creator=playlistJSON.getString("creator");
							JSONObject creatorJSON=JSONObject.parseObject(creator);
							// 创建人ID
							info.setUserId(userPlayListRequest.getUid());
							// 创建人昵称
							String nickname=creatorJSON.getString("nickname");
							info.setCreator(nickname);
							// 创建人头像
							String headPic=creatorJSON.getString("avatarUrl");
							info.setHeadPic(headPic);
							// 创建时间
							Long time=playlistJSON.getLong("createTime");
							String createTime=DateTimeUtils.dateToString(new Date(time));
							info.setCreateTime(createTime);
							// 音乐数
							Integer musicCount=playlistJSON.getInteger("trackCount");
							info.setMusicCount(musicCount);	
							list.add(info);
						}
					}
				}
			}
		} catch (Exception e) {
			logger.error("获取用户歌单信息出现异常",e);
		}
		return list;
	}
	/**
	 * 获取歌单信息 如 id=101825835
	 * @param playListRequest
	 * @return
	 */
	public PlayListInfo getPlayList(PlayListRequest playListRequest){
		PlayListInfo info=null;
		if(playListRequest.getId()==null || playListRequest.getId()<1){
			logger.error("缺少参数或出现不能识别的参数");
			throw new MyMusicException("a parameter is missing or unrecognized");
		}
		StringBuffer buffer=new StringBuffer();
		JSONObject searchRequestJSON=(JSONObject) JSONObject.toJSON(playListRequest);
		for (Entry<?, ?> entry : searchRequestJSON.entrySet()) {
			buffer.append("&" + entry.getKey() + "=" + entry.getValue());
		}
		buffer.replace(0, 1, "");
		logger.debug("歌单信息入参----->>{}",buffer.toString());
		pUtils.setKey("playlist");
		try {
			String resp=HTTPUtils.sendGet(pUtils.getStringValue(), buffer.toString());
			logger.debug("歌单信息出参----->>{}",resp);
			if(!resp.isEmpty()){
				JSONObject respJSON = JSONObject.parseObject(resp);
				if (respJSON.getInteger("code")== 200) {
					if(respJSON.containsKey("result")){
						String result=respJSON.getString("result");
						JSONObject resultJSON = JSONObject.parseObject(result);
						info=new PlayListInfo();
						// 名称
						String name=resultJSON.getString("name");
						info.setName(name);
						// ID
						String pid=resultJSON.getString("id");
						info.setId(pid);
						// 封面
						String cover=resultJSON.getString("coverImgUrl");
						info.setCover(cover);
						// 创建人信息
						String creator=resultJSON.getString("creator");
						JSONObject creatorJSON=JSONObject.parseObject(creator);
						// 创建人ID
						Integer userId=resultJSON.getInteger("userId");
						info.setUserId(userId);
						// 创建人昵称
						String nickname=creatorJSON.getString("nickname");
						info.setCreator(nickname);
						// 创建人头像
						String headPic=creatorJSON.getString("avatarUrl");
						info.setHeadPic(headPic);
						// 创建时间
						Long time=resultJSON.getLong("createTime");
						String createTime=DateTimeUtils.dateToString(new Date(time));
						info.setCreateTime(createTime);
						// 音乐数
						Integer musicCount=resultJSON.getInteger("trackCount");
						info.setMusicCount(musicCount);	
						// 音乐列表
						if(resultJSON.containsKey("tracks")){
							JSONArray tracksJSONArray=resultJSON.getJSONArray("tracks");
							List<MusicInfo> list=new ArrayList<>();
							MusicInfo musicInfo=null;
							for (int i = 0; i < tracksJSONArray.size(); i++) {
								String track=tracksJSONArray.getString(i);
								JSONObject trackJSON=JSONObject.parseObject(track);
								musicInfo=new MusicInfo();
								// 歌名
								String songname = trackJSON.getString("name");
								musicInfo.setName(songname);						
								// 歌曲ID
								String id = trackJSON.getString("id");
								musicInfo.setId(id);
								// MID
								musicInfo.setMid(id);
								// 歌曲外链
								//pUtils.setKey("src");
								//String src=pUtils.getStringValue().replace("SONGID", id);
								//musicInfo.setSrc(src);
								JSONArray artistsArray = trackJSON.getJSONArray("artists");
								// 歌手 艺术家
								StringBuffer artist = new StringBuffer();
								for (int j = 0; j < artistsArray.size(); ++j) {
									String artists = artistsArray.getString(j);
									JSONObject artistsJSON = JSONObject.parseObject(artists);
									artist.append(artistsJSON.getString("name"));
									if (j < artistsArray.size() - 1) {
										artist.append("/");
									}
								}
								musicInfo.setSinger(artist.toString());
								// 专辑
								String album = trackJSON.getString("album");
								JSONObject albumJSON = JSONObject.parseObject(album);
								String albumName=albumJSON.getString("name");
								musicInfo.setAlbum(albumName);
								// 封面
								String songcover = albumJSON.getString("picUrl");
								musicInfo.setCover(songcover);
								if(playListRequest.getShowLrc()!=0){
									// 歌词
									String lyric = getMusicLyric(id);	
									musicInfo.setLyric(lyric);
								}
								list.add(musicInfo);
								
							}
							info.setMusicList(list);
							
						}
						}
					}
				}
		} catch (Exception e) {
			logger.error("获取歌单信息出现异常",e);
		}
		return info;
	}
	/**
	 * 获取外链
	 * @param mid
	 * @return
	 */
	public String getMusicSrc(String mid){
		pUtils.setKey("src");
		return pUtils.getStringValue().replace("SONGID", mid);
	}
	/**
	 * 获取歌词信息
	 * @param id 音乐ID
	 * @return
	 */
	public String getMusicLyric(String id){
		String lyric=null;
		StringBuffer buffer=new StringBuffer();
		JSONObject lyricRequestJSON=new JSONObject();
		lyricRequestJSON.put("os", "pc");
		lyricRequestJSON.put("id", id);
		lyricRequestJSON.put("lv", -1);
		lyricRequestJSON.put("kv", -1);
		lyricRequestJSON.put("tv", -1);
		for (Entry<?, ?> entry : lyricRequestJSON.entrySet()) {
			buffer.append("&" + entry.getKey() + "=" + entry.getValue());
		}
		buffer.replace(0, 1, "");
		logger.debug("歌词信息入参----->>{}",buffer.toString());
		// 歌词
		pUtils.setKey("lyric");
		try {
			String lyricResp =HTTPUtils.sendGet(pUtils.getStringValue(), buffer.toString());
			logger.debug("歌词信息出参---->>{}",lyricResp);
			if(!lyricResp.isEmpty()){
				JSONObject lyricRespJson = JSONObject.parseObject(lyricResp);
				if (lyricRespJson.getInteger("code")== 200) {
					if(lyricRespJson.containsKey("lrc")){
						String lrc = lyricRespJson.getString("lrc");
						JSONObject lrcJSON = JSONObject.parseObject(lrc);
						lyric = lrcJSON.getString("lyric");						
					}
				}
			}
		} catch (Exception e) {
			logger.error("获取歌词信息出现异常！",e);
		}	
		return lyric;
	}
}
